<!-- 广告管理 -->
<template>
  <div>
    <el-header>
      <el-space wrap>
        <el-select v-model="initConfig.status" clearable placeholder="请选择广告状态">
          <el-option
            v-for="item in options.status"
            :key="item.value"
            :label="item.name"
            :value="item.value"
          />
        </el-select>
        <el-select v-model="initConfig.type" clearable placeholder="请选择广告类型">
          <el-option
            v-for="item in options.type"
            :key="item.value"
            :label="item.name"
            :value="item.value"
          />
        </el-select>
        <el-button type="primary" :icon="Search" @click="initData">查找</el-button>
        <el-button
          type="primary"
          :icon="Plus"
          @click="
            () => {
              titleDialog = '创建';
              dialogShow = true;
              resetData();
            }
          "
          >添加</el-button
        >
      </el-space>
    </el-header>
    <el-container v-loading="loading">
      <!-- 列表 -->
      <el-table :data="advertData" border align="center">
        <el-table-column prop="id" label="广告ID" align="center" width="90" />
        <el-table-column prop="title" label="广告标题" align="center" />
        <el-table-column label="广告图片" align="center" width="140">
          <template #default="scope">
            <el-popover
              placement="right"
              :width="250"
              trigger="hover"
              v-if="scope.row.type < 6"
            >
              <template #reference>
                <el-image style="height: 35px" :src="scope.row.imgUrl" />
              </template>
              <el-image style="width: 100%" :src="scope.row.imgUrl" />
            </el-popover>
            <el-tag type="info" v-else>类型无需图片</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="广告类型" align="center" width="150">
          <template #default="scope">
            <el-tag>{{
              options.type.find((item) => item.value == scope.row.type)?.name
            }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="广告状态" align="center" width="100">
          <template #default="scope">
            <el-tag :type="scope.row.status ? 'success' : 'danger'">{{
              scope.row.status ? "激活" : "冻结"
            }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="关联类型" align="center" width="100">
          <template #default="scope">
            <el-tag>{{
              options.unionType.find((item) => item.value == scope.row.unionType)?.name
            }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="关联值[ID]" align="center">
          <template #default="scope">
            {{ scope.row.unionValue }}
          </template>
        </el-table-column>
        <el-table-column label="创建时间" align="center">
          <template #default="scope">
            {{ new Date(scope.row.gmtCreate).computeDate() }}
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" width="200">
          <template #default="scope">
            <el-button type="primary" @click="editData(scope.row)">编辑</el-button>
            <el-button type="danger" @click="daleAdvert(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 弹窗 -->
      <el-dialog v-model="dialogShow" :title="titleDialog" width="700px" destroy-on-close>
        <el-form
          ref="formRef"
          :model="dialogFrom"
          :rules="rules"
          :label-width="100"
          status-icon
        >
          <el-form-item label="广告标题" prop="title">
            <el-input v-model.trim="dialogFrom.title" type="text" />
          </el-form-item>
          <el-form-item label="广告类型" prop="type">
            <el-select
              v-model="dialogFrom.type"
              placeholder="请选择"
              @change="dialogFrom.unionType = null"
            >
              <el-option
                v-for="item in options.type"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item
            label="广告图片"
            prop="imgUrl"
            id="img_box"
            :style="'background:' + dialogFrom.color"
            v-if="showImg"
          >
            <el-upload
              class="avatar-uploader"
              :show-file-list="false"
              :headers="headers"
              :action="action"
              @success="afterSuccess"
              @error="afterError"
            >
              <img
                v-if="dialogFrom.imgUrl"
                :src="dialogFrom.imgUrl"
                style="height: 150px"
              />
              <el-icon v-else class="avatar-uploader-icon">
                <Plus />
              </el-icon>
            </el-upload>
          </el-form-item>
          <el-form-item label="广告状态" prop="status">
            <el-switch
              v-model="dialogFrom.status"
              :active-value="1"
              :inactive-value="0"
              class="ml-2"
              style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
            />
          </el-form-item>
          <el-form-item label="关联类型" prop="unionType">
            <el-select
              v-model="dialogFrom.unionType"
              :placeholder="dialogFrom.type ? '点击时跳转目标' : '请先选择广告类型'"
              @change="dialogFrom.unionValue = ''"
            >
              <el-option
                v-for="item in options.unionType"
                :disabled="switchUnionType(item.value)"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item v-if="dialogFrom.unionType == 1" label="商品" prop="unionValue">
            <el-cascader
              v-model="dialogFrom.unionValue"
              :props="propsA"
              placeholder="关联至商品"
              :options="suBigList"
              :show-all-levels="false"
            />
          </el-form-item>
          <el-form-item
            v-else-if="dialogFrom.unionType == 2"
            label="类目"
            prop="unionValue"
          >
            <el-cascader
              v-model="dialogFrom.unionValue"
              :props="propsB"
              placeholder="关联至类目"
              :options="categorytList"
              :show-all-levels="false"
            />
          </el-form-item>
          <el-form-item
            v-else-if="dialogFrom.unionType == 3"
            label="关键字"
            prop="unionValue"
          >
            <el-input v-model.trim="dialogFrom.unionValue" type="text" />
          </el-form-item>
          <el-form-item
            v-else-if="dialogFrom.unionType == 4"
            label="功能页面"
            prop="unionValue"
          >
            <el-select v-model="dialogFrom.unionValue" placeholder="请选择一个功能页面">
              <el-option
                v-for="item in options.featurePage"
                :key="item.value"
                :label="item.name"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-form>
        <template #footer>
          <span>
            <el-button @click="dialogShow = false">取消</el-button>
            <el-button type="primary" @click="submitForm(formRef)">确定</el-button>
          </span>
        </template>
      </el-dialog>
    </el-container>
    <el-footer>
      <!-- 分页组件 -->
      <ElPagination
        :total="pageInfo.total"
        :limit="pageInfo.limit"
        @changeReq="changeConfig"
      ></ElPagination>
    </el-footer>
  </div>
</template>

<script setup lang="ts">
import Cookie from "js-cookie";
import { post } from "@/request/http";
import { Search, Plus } from "@element-plus/icons-vue";
import { ref, reactive, computed, watch, onMounted } from "vue";
import   {type  FormInstance, type UploadProps,ElMessage, ElMessageBox } from "element-plus";
import { colorImg } from "@/utils/color/average";
// 广告关联类型
const adUinonTypeMap = ref([
  { value: 1, name: "商品" },
  { value: 2, name: "类目" },
  { value: 3, name: "关键字" },
  { value: 4, name: "功能页面" },
]);

//广告类型
const adTypeMap = ref([
  { value: 1, unionTypes: [1, 2, 3, 4], picRequire: true, name: "轮播" },
  { value: 2, unionTypes: [2], picRequire: true, name: "分类精选" },
  { value: 3, unionTypes: [1, 2, 3, 4], picRequire: true, name: "横幅" },
  { value: 4, unionTypes: [1, 2, 3, 4], picRequire: true, name: "首页轮播下5按钮" },
  { value: 6, unionTypes: [1, 2, 3, 4], picRequire: false, name: "公告" },
  { value: 9, unionTypes: [1], picRequire: false, name: "商品推荐" },
]);
//广告状态
const adStatusMap = ref([
  { value: 0, name: "冻结" },
  { value: 1, name: "激活" },
]);

//功能页面
const functionPages = ref([
  { value: "/pages/product/groupshop", name: "团购列表" },
  { value: "/pages/coupon/list", name: "优惠券列表" },
]);

let advertData = ref([]);
let dialogShow = ref(false); //是否显示弹出框
let titleDialog = ref(""); //弹窗框的标题
let loading = ref(true);
const formRef = ref(); //表单节点
const headers = computed(() => {
  return { AdminToken: Cookie.get("token") };
});
const action = "/upload/admin";
// 页面加载的请求数据
let initConfig: any = reactive({
  _gp: "admin.advert",
  _mt: "list",
  status: null,
  type: null,
  limit: 20,
  pageNo: 1,
});

// 添加修改的数据
let dialogFrom: any = reactive({
  _gp: "admin.advert",
  _mt: "",
  title: "", //广告标题
  type: null, //类型
  imgUrl: "", //广告图片地址
  color: "", //图片均颜色
  status: 1, //广告状态
  unionType: null, //关联类型
  unionValue: "", //关联值
});

// 传给分页组件的数据
let pageInfo = reactive({
  page: 1, //跳转页数
  limit: 10, //显示条数
  total: 0,
});
let categorytList = ref([]); //类目配置数据
let suBigList = ref([]); //商品配置数据
// 下拉框的配置
let options = reactive({
  status: adStatusMap,
  type: adTypeMap,
  unionType: adUinonTypeMap,
  featurePage: functionPages,
});

// 表单验证的规则
let rules = reactive({
  title: [{ required: true, message: "请输入广告标题" }], // ---广告标题
  type: [{ required: true, message: "请输入广告类型", trigger: "change" }], // ---广告类型
  status: [{ required: true, message: "" }], // ---广告状态
  imgUrl: [{ required: true, message: "请提交图片" }], // ---图片
  unionType: [{ required: true, message: "请选择关联类型", trigger: "change" }], // ---广告关联类型
  unionValue: [
    {
      required: true,
      message: "请选择一个(商品、类目、页面等具体值)",
      trigger: "change",
    },
  ], // ---广告关联类型值
});

// 商品级联选择器的配置

let propsA = reactive({
  label: "label",
  children: "children",
  value: "id",
  emitPath: false,
});

// 类目级联选择器的配置
let propsB = reactive({
  label: "title",
  children: "childrenList",
  value: "id",
  emitPath: false,
});

// 获取商品和类目数据的方法
const getTree = () => {
  post({ _gp: "admin.category", _mt: "categoryTree" }).then((res) => {
    if (200 == res.errno) {
      categorytList.value = res.data;
    }
  });
  post({ _gp: "admin.product", _mt: "getSpuBigTree" }).then((res) => {
    if (200 == res.errno) {
      suBigList.value = res.data;
    }
  });
};
// 分页切换触发
const changeConfig = (e: { page: number; limit: number }) => {
  Object.assign(initConfig, { limit: e.limit, pageNo: e.page });
  initData();
};
//变量提示的时候可能为赋值，但是函数提升不会
const initData = () => {
  post(initConfig).then((res) => {
    if (200 == res?.errno) {
      // console.log(res.data)
      advertData.value = res.data.items;
      pageInfo.total = res.data.total; //获取总条数
      loading.value = false;
    }
  });
};

// 删除广告
const daleAdvert = (row: any) => {
  ElMessageBox.confirm("是否删除该广告?", "提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      post({
        _gp: "admin.advert",
        _mt: "delete",
        adId: row.id,
        type: row.type,
      }).then((res) => {
        if (200 == res.errno) {
          ElMessage.success("删除成功");
          initData();
        }
      });
    })
    .catch(() => {
      ElMessage.info("删除取消");
    });
};

// 关联类型判断是否禁用
const switchUnionType = (value: any) => {
  let type = dialogFrom.type; //获取表单中类型
  if (!type) return true;
  let unionTypes = (options.type.find((i: any) => i.value == type) as any)?.unionTypes; //获取不禁用关联类型的数组
  if (unionTypes.indexOf(value) == -1) return true;
  return false;
};
// 判断表单中的类型是否需要图片
const showImg = computed(() => {
  return (options.type.find((item) => dialogFrom.type == item.value) as any)?.picRequire;
});
// 重置表单数据
const resetData = () => {
  Object.assign(dialogFrom, {
    _gp: "admin.advert",
    _mt: "",
    title: "", //广告标题
    type: null, //类型
    imgUrl: "", //广告图片地址
    color: "", //图片均颜色
    status: 1, //广告状态
    unionType: null, //关联类型
    unionValue: "", //关联值
  });
};

// 编辑时
const editData = (row: any) => {
  resetData(); //重置数据
  let { title, type, imgUrl, color, status, unionType, unionValue, id: adId } = row; //获取行内信息
  unionValue = +unionValue; //转型
  dialogFrom.color = color; //获取到颜色
  // 如果是无需图片的类型把它的默认图片删除
  if (type >= 6) imgUrl = "";
  Object.assign(dialogFrom, {
    title,
    type,
    imgUrl,
    color,
    status,
    unionType,
    unionValue,
    adId,
  });
  titleDialog.value = "修改";
  dialogShow.value = true;
};

// 提交图片的函数
const afterSuccess: UploadProps["onSuccess"] = (
  response: any,
  uploadFile,
  uploadFiles
) => {
  dialogFrom.imgUrl = response.url;
  colorImg(response.url, (e: any) => {
    dialogFrom.color = e;
  });
};
const afterError: UploadProps["onError"] = (errno: any, uploadFile, uploadFiles) => {
  console.log(errno);
};

// 提交表单数据
const submitForm = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.validate((valid) => {
    if (valid) {
      let data = Object.assign({}, dialogFrom);
      data.imgUrl = showImg.value
        ? data.imgUrl
        : "https://www.baidu.com/img/flexible/logo/pc/result.png"; //不需要图片添加默认图片
      data._mt = titleDialog.value == "创建" ? "create" : "edit"; //判断是编辑还是添加
      post(data).then((res) => {
        if (200 == res.errno) {
          dialogShow.value = false; //关闭弹窗
          ElMessage.success(titleDialog.value + "成功");
          initData(); //刷新数据
        }
      });
    }
  });
};

onMounted(() => {
  initData();
});
watch(dialogShow, (n) => {
  if (categorytList.value.length != 0) return; //长度不为0时获取树
  if (n) getTree();
});
</script>

<style scoped>
.el-header {
  height: auto;
  margin-bottom: 20px;
}
.el-form {
  display: flex;
  flex-wrap: wrap;
  width: 70%;
  margin-left: 15%;
}
.el-form-item {
  width: 100%;
}
.el-icon.avatar-uploader-icon {
  border-radius: 6px;
  border: 1px dashed var(--el-border-color);
  font-size: 28px;
  color: #8c939d;
  width: 150px;
  height: 150px;
  text-align: center;
}
</style>
